package com.legsem.jhosync.source;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;

import com.legsem.jhosync.Context;
import com.legsem.jhosync.face.SourceAdapter;
import com.legsem.jhosync.face.SourceAdapterException;

/**
 * An implementation of a Source for test purposes.
 * <p/>
 * The annotation is omitted on purpose since it is needed only for discovery
 * from the classpath and we don't want to interfere
 * 
 */
public class CustomerSource extends SourceAdapter {

    private static final Map < String, Map < String, Object >> MOCK_STORAGE = new HashMap < String, Map < String, Object >>();
    static {
        init();
    }

    /**
     * Mock some initial content.
     */
    public static synchronized void init() {
        MOCK_STORAGE.clear();
        Map < String, Object > attrs = new HashMap < String, Object >();
        attrs.put("address",
                "Perspective Défense 1 à 5 r du Débarcadère 92700 COLOMBES ");
        attrs.put("company", "AREVA");
        attrs.put("name", "Aristide Gonfland");
        attrs.put("created_at", "2011-04-12T15:06:04Z");
        attrs.put("updated_at", "2011-04-12T15:09:23Z");
        attrs.put("phone", "+33(0)134961000");
        attrs.put("lat", "48.9079465717798");
        attrs.put("long", "2.23419427871704");
        MOCK_STORAGE.put("2", attrs);
    }

    private Random generator = new Random();

    public void login(Context context) throws SourceAdapterException {
        String username = (String) context
                .getSessionAttribute("salesman.username");
        if (username == null || username.length() == 0) {
            throw new SourceAdapterException(
                    String.format("User name is unknown"));
        }
    }

    public synchronized Map < String, Map < String, Object > > query(
            Map < String, Object > params) throws SourceAdapterException {
        if (params != null) {
            throw new SourceAdapterException(
                    "This source query does not support parameters");
        }
        Map < String, Map < String, Object >> results = new HashMap < String, Map < String, Object >>(
                MOCK_STORAGE);
        return results;

    }

    public synchronized String create(Map < String, Object > params)
            throws SourceAdapterException {

        String id = null;
        // Trick to get an id known in advance
        if (params.get("id") != null) {
            if (params.get("id").equals("null")) {
                return null;
            } else if (params.get("id").equals("exception")) {
                throw new SourceAdapterException("BounceException");
            } else {
                id = params.get("id").toString();
            }
        } else {
            id = Integer.toString(generator.nextInt());
        }
        MOCK_STORAGE.put(id, params);
        return id;
    }

    public synchronized void update(Map < String, Object > attributes)
            throws SourceAdapterException {
        String id = (String) attributes.get("id");
        if (id == null) {
            throw new SourceAdapterException("id is null");
        } else if (id.equals("exception")) {
            throw new SourceAdapterException("BounceException");
        }
        if (MOCK_STORAGE.get(id) == null) {
            throw new SourceAdapterException("id is unknown " + id);
        }
        for (Entry < String, Object > entry : attributes.entrySet()) {
            MOCK_STORAGE.get(id).put(entry.getKey(), entry.getValue());
        }

    }

    public synchronized void delete(Map < String, Object > attributes)
            throws SourceAdapterException {
        String id = (String) attributes.get("id");
        if (id == null) {
            throw new SourceAdapterException("id is null");
        } else if (id.equals("exception")) {
            throw new SourceAdapterException("BounceException");
        }
        if (MOCK_STORAGE.get(id) == null) {
            throw new SourceAdapterException("id is unknown " + id);
        }
        MOCK_STORAGE.remove(id);

    }

    public void logoff() throws SourceAdapterException {

    }

}
